package main

import (
	"fmt"
	"io"
)

// List 接口

type List interface {
	Add(index int, val any)
	Append(val any)
	Delete(index int)
}

type node struct {
	data int   // 节点存储的数据
	next *node // 指向下一个节点的指针
}

// LinkedList 公开类型  结构体实现接口
type LinkedList struct {
	head *node
	//Head *node
}

// Add 添加一个元素
func (l *LinkedList) Add(index int, val any) {
	//TODO implement me 实现我
	panic("implement me")
}
func (l *LinkedList) Append(val any) {
	//TODO implement me
	panic("implement me")
}
func (l *LinkedList) Delete(index int) {
	panic("implement me")
}

type User struct {
	Name string
	Age  int
}

func StructInit() {
	//u1 是指向一个User对象的指针
	u1 := &User{}
	fmt.Println(u1)

	// u2中的字段是零值
	u2 := User{}
	fmt.Println(u2)
	// 修改 u2的字段
	u2.Name = "jerry"
	// u3中的字段也都是零值
	var u3 User
	fmt.Println(u3)
}

func StructFieldInit() {
	// 初始化的同时，还赋值了Name
	var u4 User = User{Name: "Tome"}
	fmt.Println(u4)

	// 没有指定字段名，按照字段顺序赋值
	// 必须全部赋值
	var u5 User = User{"Tom", 18}
	fmt.Println(u5)
}

func UseList() {
	l1 := LinkedList{}
	l1Ptr := &l1
	var l2 LinkedList = *l1Ptr
	fmt.Println(l2)
	// 这个是nil
	var l3Ptr *LinkedList
	fmt.Println(l3Ptr)
}

// 方法接收器
func (u User) ChangeName(name string) {
	fmt.Printf("u address %p\n", &u)
	u.Name = name
}

func (u User) ChangeAge(age int) {
	u.Age = age

}

func ChangeUser() {
	u1 := User{"Tom", 18}
	fmt.Printf("#{u1} \n")
	fmt.Printf("u1 address %p\n", &u1)

	u1.ChangeName("Jerry")
	u1.ChangeAge(35)
	fmt.Printf("#{u1} \n")

	u2 := &User{Name: "小明", Age: 18}
	fmt.Printf("#{u2} \n")
	fmt.Printf("u2 address #{u2}\n")

	u2.ChangeName("Jerry")
	u2.ChangeAge(35)
	fmt.Printf("#{u2} \n")

}

type Fish struct{}

// Swim 方法，Fish 结构体的方法
func (f Fish) Swim() {
	fmt.Println("Fish is swimming")
}

// FakeFish 结构体
type FakeFish struct{}

// FakeSwim 方法，FakeFish 结构体的方法
func (f FakeFish) FakeSwim() {
	fmt.Println("FakeFish is swimming")
}

// 衍生类型
func UseFist() {
	f1 := Fish{}
	f1.Swim()
	f2 := FakeFish{}
	// f2 将不能调用Fish上的方法
	// 因为f2是一个全新的类型
	f2.FakeSwim()

	// 类型转换
	f3 := Fish(f2)
	f3.Swim()

	// Yu 鱼
	// 鱼是Fish的别名
	type Yu = Fish
	y := Yu{}
	y.Swim()
}

type Outer struct {
	Inner
}

type Inner struct {
}
type Outer1 struct {
	*Inner
}
type Outer2 struct {
	// 组合了接口
	io.Closer
}

func (o Outer) Name() string {
	return "Outer"
}
func (i Inner) SayHello() {
	println("hello," + i.Name())
}

func (i Inner) Name() string {
	return "Inner"
}

func UseOuter() {
	var o Outer
	o.SayHello()
}
func main() {
	//StructFieldInit()
	//UseList()
	//ChangeUser()
	//UseFist()
	UseOuter()
}
